//
//  TimeUtils.m
//   
//
//  Created by lanzhongping on 2020/12/1.
//  Copyright © 2020 linktop. All rights reserved.
//  nsdate的工具类

#import "TimeUtils.h"

@implementation TimeUtils


/// 取当天的0点时间
+ (NSDate *)zeroOfDate:(NSDate *)inputDate
{
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];


//    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:inputDate];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    NSDate *localeDate = [calendar dateFromComponents:components];
    // components.nanosecond = 0 not available in iOS
//    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
//    NSDate * date = [NSDate dateWithTimeIntervalSince1970:ts];
//    NSTimeZone *zone = [NSTimeZone systemTimeZone];
//    NSInteger interval = [zone secondsFromGMTForDate: date];
//    NSDate *localeDate = [date  dateByAddingTimeInterval: interval];
    return localeDate;
    
    
}

/// 取当天所在年的开始时间
+ (NSDate *)zeroOfYearByDate:(NSDate *)inputDate
{
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];
//    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:inputDate];
    components.month = 1;
    components.day = 1;
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    
    // components.nanosecond = 0 not available in iOS
    NSDate *localeDate = [calendar dateFromComponents:components];

//    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
//    NSDate * date = [NSDate dateWithTimeIntervalSince1970:ts];
//    NSTimeZone *zone = [NSTimeZone systemTimeZone];
//    NSInteger interval = [zone secondsFromGMTForDate: date];
//    NSDate *localeDate = [date  dateByAddingTimeInterval: interval];
    return localeDate;
    
    
}


/// 取当天的0点时间
+ (NSDate *)modifyDate:(NSDate *)inputDate newHour:(NSInteger)hour newMinute:(NSInteger)minute newSecond:(NSInteger)second
{
    if (hour < 0 || hour > 23) {
        return nil;
    }
    if (minute < 0 || minute > 60) {
        return nil;
    }
    if (second < 0 || second > 60) {
        return nil;
    }
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];
    components.hour = hour;
    components.minute = minute;
    components.second = second;
    NSDate *localeDate = [calendar dateFromComponents:components];
    // components.nanosecond = 0 not available in iOS
    //    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
    //    NSDate * date = [NSDate dateWithTimeIntervalSince1970:ts];
    //    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    //    NSInteger interval = [zone secondsFromGMTForDate: date];
    //    NSDate *localeDate = [date  dateByAddingTimeInterval: interval];
    return localeDate;
    
    
}


/// 取下一天的0点时间
+ (NSDate *)zeroOfNextDayDate:(NSDate *)inputDate {
    NSDate *todayZero = [self zeroOfDate:inputDate];
    NSDate *nextDayDate = [todayZero dateByAddingTimeInterval:24 * 3600];
//    NSCalendar *calendar = [NSCalendar currentCalendar];
//    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:inputDate];
//    components.hour = 0;
//    components.minute = 0;
//    components.second = 0;
//
//    // components.nanosecond = 0 not available in iOS
//    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
//    NSDate * date = [NSDate dateWithTimeIntervalSince1970:ts];
//    NSTimeZone *zone = [NSTimeZone systemTimeZone];
//    NSInteger interval = [zone secondsFromGMTForDate: date];
//    interval += (24 * 3600);
//    NSDate *nextDayDate = [date  dateByAddingTimeInterval: interval];
    return nextDayDate;
    
}

/// 取前一天的0点时间
+ (NSDate *)zeroOfBeforeDayDate:(NSDate *)inputDate
{
    
//    NSCalendar *calendar = [NSCalendar currentCalendar];
//    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:inputDate];
//    components.hour = 0;
//    components.minute = 0;
//    components.second = 0;
//    NSInteger week = components.weekday;
//
//    // components.nanosecond = 0 not available in iOS
//    NSTimeInterval ts = (double)(int)[[calendar dateFromComponents:components] timeIntervalSince1970];
//    NSDate * date = [NSDate dateWithTimeIntervalSince1970:ts];
//    NSTimeZone *zone = [NSTimeZone systemTimeZone];
//    NSInteger interval = [zone secondsFromGMTForDate: date];
//    interval -= (24 * 3600);
//    NSDate *nextDayDate = [date  dateByAddingTimeInterval: interval];
    
    NSDate *todayZero = [self zeroOfDate:inputDate];
    NSDate *beforeDayDate = [todayZero dateByAddingTimeInterval:-24 * 3600];
    
    return beforeDayDate;
    
}


/// 取出月中第几号
/// @param inputDate 日期
+(NSInteger)getDayOfMonth:(NSDate *)inputDate
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];//    NSInteger week = components.weekOfYear;
    return  components.day;
}

+(void)getYearMonthDayFromDate:(NSDate *)inputDate Cmp:(void(^)(NSInteger year, NSInteger month, NSInteger day))BLk
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];    if (BLk) {
        BLk(components.year , components.month, components.day);
    }
    
}


//取出在一天中的第几小时 24小时制
+(NSInteger)getHour:(NSDate *)inputDate
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];//    NSInteger week = components.weekOfYear;
    return  components.hour;
}


/// inputDate开始倒数 days 的0点0分时间
/// @param days 倒数天数
/// @param inputDate 其实日期
+(NSDate *)getDayDateBefore:(NSUInteger)days From:(NSDate *)inputDate
{
    
    NSDate *zeroDate = [self zeroOfDate:inputDate];
    NSTimeInterval timeINteval = [zeroDate timeIntervalSince1970];
    timeINteval -= (days * 24 * 3600);
    return [NSDate dateWithTimeIntervalSince1970:timeINteval];
    
}


/// 计算属于一年中的第几天
/// @param inputDate
+(NSInteger)getDayOfYear:(NSDate *)inputDate
{
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * components = [calendar components:unitFlags fromDate:inputDate];    components.month = 1;
    components.day = 1;
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    
    NSDateComponents *beginComponents = [[NSDateComponents alloc] init];
    [beginComponents setYear:components.year];
    [beginComponents setMonth:1];
    [beginComponents setDay:1];
    [beginComponents setHour:0];
    [beginComponents setMinute:0];
    [beginComponents setSecond:0];
    
    
    NSDate *beginData = [calendar dateFromComponents:beginComponents];
    NSTimeInterval ts = [beginData timeIntervalSince1970];
    
    NSTimeInterval tsEnd = [inputDate timeIntervalSince1970];
    
    NSInteger day =  ((NSInteger)(tsEnd - ts)) / (24 * 3600) ; // 第几天
    return day;
}

+(NSDate *)transToDateBy:(NSNumber *)year Month:(NSNumber *)month Day:(NSNumber *)day
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute |NSCalendarUnitSecond;
    NSDateComponents * beginComponents = [calendar components:unitFlags fromDate:[NSDate date]];
    [beginComponents setYear:year.integerValue];
    [beginComponents setMonth:month.integerValue];
    [beginComponents setDay:day.integerValue];
    [beginComponents setHour:0];
    [beginComponents setMinute:0];
    [beginComponents setSecond:0];
    NSDate *date = [calendar dateFromComponents:beginComponents];
    return date;
}

//NSString转NSDate
+(NSDate *)dateFromString:(NSString *)dateString DateFormat:(NSString *)DateFormat
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:DateFormat];
    NSDate *destDate= [dateFormatter dateFromString:dateString];
    return destDate;
}
 
//获取年月日对象
+(NSDateComponents *)getDateComponents:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    return [calendar components:
            NSCalendarUnitYear|
            NSCalendarUnitMonth|
            NSCalendarUnitDay|
            NSCalendarUnitWeekOfYear|
            NSCalendarUnitQuarter fromDate:date];
}
 
//获得某年的周数
+(NSInteger)getWeekAccordingToYear:(NSInteger)year
{
    
    NSDateComponents *comps = [TimeUtils getDateComponents:[TimeUtils dateFromString:[NSString stringWithFormat:@"%ld-12-31",(long)year] DateFormat:@"yyyy-MM-dd"]];
    NSInteger week = [comps weekOfYear];
    if (week == 1) {
        return 52;
    }else {
        return week;
    }
}
 
/**
 *  获取某年某周的范围日期
 *
 *  @param year       年份
 *  @param weekofYear year里某个周
 *
 *  @return 时间范围字符串
 */
+(NSArray<NSDate *> *)getWeekRangeDate_Year:(NSInteger)year WeakOfYear:(NSInteger)weekofYear
{
//    NSString *weekDate = @"";
    NSString *timeAxis = [NSString stringWithFormat:@"%ld-06-01 00:00:00",(long)year];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *date = [dateFormatter dateFromString:timeAxis];
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    /**这两个参数的设置影响着周次的个数和划分*****************/
    [calendar setFirstWeekday:1]; //设置每周的开始是星期一
    [calendar setMinimumDaysInFirstWeek:7]; //设置一周至少需要几天
    NSDateComponents *comps = [calendar components:(NSCalendarUnitWeekOfYear | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                          fromDate:date];
    //时间轴是当前年的第几周
    NSInteger todayIsWeek = [comps weekOfYear];
    if ([self getWeekAccordingToYear:year] == 53) {
        todayIsWeek += 1;
    }
    //获取时间轴是星期几 1(星期天) 2(星期一) 3(星期二) 4(星期三) 5(星期四) 6(星期五) 7(星期六)
    NSInteger todayIsWeekDay = [comps weekday];
    // 计算当前日期和这周的星期一和星期天差的天数
    //firstDiff 星期一相差天数 ", lastDiff 星期天相差天数
    long firstDiff,lastDiff;
    if (todayIsWeekDay == 1) {
        firstDiff = -6;
        lastDiff = 0;
    }else
    {
        firstDiff = [calendar firstWeekday] - todayIsWeekDay;
        lastDiff = 8 - todayIsWeekDay;
    }
    
    NSDate *firstDayOfWeek= [NSDate dateWithTimeInterval:24*60*60*firstDiff sinceDate:date];
    NSDate *lastDayOfWeek= [NSDate dateWithTimeInterval:24*60*60*lastDiff sinceDate:date];
    
    long weekdifference = weekofYear - todayIsWeek;
    
    firstDayOfWeek= [NSDate dateWithTimeInterval:24*60*60*7*weekdifference sinceDate:firstDayOfWeek];
    lastDayOfWeek= [NSDate dateWithTimeInterval:(24*60*60*7*weekdifference - 1) sinceDate:lastDayOfWeek];
    

    return @[firstDayOfWeek, lastDayOfWeek];
}

+(NSString *)getStringOfMonth:(NSNumber *)month {
    /*
     January一月 Jan",
     February二月 Feb",
     March三月 Mar",
     April四月 Apr",
     May五月 May",
     June六月 Jun",
     
     July七月 Jul",
     August八月 Aug",
     Septemper九月 Sep",
     October十月 Oct",
     November十一 月Nov",
     December十二月  Dec*/
    static  NSDictionary<NSNumber *, NSString *> *monthDict = nil;
    
    static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            monthDict = @{
                @1 : @"Jan",
                @2 : @"Feb",
                @3 : @"Mar",
                @4 : @"Apr",
                @5 : @"May",
                @6 : @"Jun",
                @7 : @"Jul",
                @8 : @"Aug",
                @9 : @"Sep",
                @10 :@"Oct",
                @11 :@"Nov",
                @12 :@"Dec",
            };
        });
    
    return monthDict[month];
    
}


/// 计算是否闰年
/// @param year 年份
+(BOOL)bissextile:(int)year {
     if ((year%4==0 && year %100 !=0) || year%400==0) {
            return YES;
     }else {
           return NO;
     }
     return NO;
}

// 获取一年中所有日期,按周分组
+(NSMutableArray<NSMutableArray <NSDate *> *> *)everyWeekDatesOfYearGroupByWeak:(NSUInteger)year FirstDayOfWeek:(NSUInteger)firstDayOfWeek
{
    
    NSMutableArray<NSMutableArray <NSDate *> *> *allArray = [NSMutableArray arrayWithCapacity:52]; // 一年52 周
    
    if (firstDayOfWeek < 1 || firstDayOfWeek > 7) {
        firstDayOfWeek = 1;
    }
    
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    calendar.firstWeekday = firstDayOfWeek;

    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.yearForWeekOfYear = year;
    
    for (int i = 1; i <= 52; i++) { // 周循环
        components.weekOfYear = i;
        NSMutableArray<NSDate *> * dateArray = [NSMutableArray new];
        for (int j = 1; j <= 7; j++) { // 周内循环
            [components setWeekday:j];
            NSDate * date = [calendar dateFromComponents:components];
            [dateArray addObject:date];
        }
        
        [allArray addObject:dateArray];
    }
    
    return allArray;
    
}


/// 周的日期
/// @param year 年
/// @param firstDayOfWeek 每周第一天是周几 1=周日
+(NSMutableArray<NSMutableArray<NSMutableArray<NSDate *> *> *> *)serverialWeekRangeDatesOfYear:(NSUInteger)year FirstDayOfWeek:(NSUInteger)firstDayOfWeek
{
    
    NSMutableArray<NSMutableArray<NSMutableArray<NSDate *> *> *> *allArray = [NSMutableArray new];
    
    if (firstDayOfWeek < 1 || firstDayOfWeek > 7) {
        firstDayOfWeek = 1;
    }
    
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    calendar.firstWeekday = firstDayOfWeek;

    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.yearForWeekOfYear = year;
    NSMutableArray<NSMutableArray<NSDate *> *> * groupArray = [NSMutableArray new];
    
    for (int i = 1; i <= 52; i++) { // 周循环
        NSMutableArray *weekDateArray = [NSMutableArray new];
        components.weekOfYear = i;
        
        [components setWeekday:1]; // 周开始日期
        NSDate * weekStartDate = [calendar dateFromComponents:components];
        [weekDateArray addObject:weekStartDate];
        
        [components setWeekday:7]; // 周结束日期
        NSDate * weekEndDate = [calendar dateFromComponents:components];
        [weekDateArray addObject:weekEndDate];
        
        [groupArray addObject:weekDateArray];
        weekDateArray = [NSMutableArray new];
        
        if (i % 8 == 0 || i == 52) { // 8 个
            [allArray addObject:groupArray];
            groupArray = [NSMutableArray new];
        }
       
    }
    
    return allArray;
    
}

+(NSMutableArray <NSMutableArray<NSDate *> *>*)monthRangeDateofYear:(NSUInteger)year
{
    
    NSMutableArray <NSMutableArray<NSDate *> *>* allArray = [NSMutableArray new];
    
    NSDateFormatter *monthBeginFormatter = [[NSDateFormatter alloc]init];
    monthBeginFormatter.dateFormat = @"yyyy-MM-dd";
    NSDateFormatter *monthEndFormatter = [[NSDateFormatter alloc]init];
    
    NSString *formatBase = @"%d-%d-1";
    
//
    for (int i = 1; i <= 12; i++) {
        NSMutableArray<NSDate *> *monthRangeArray = [NSMutableArray new];
        int j = i + 1;
       
        NSString *beginDateString = [NSString stringWithFormat:formatBase, year, i];
//        monthBeginFormatter.dateFormat = ;
        NSDate *beginDate = [monthBeginFormatter dateFromString:beginDateString];
        [monthRangeArray addObject:beginDate];
        
        if (i == 12) {
            year += 1;
            j = 1;
        }
        NSString *endDateString = [NSString stringWithFormat:formatBase, year, j];
//        monthBeginFormatter.dateFormat = ;
        NSDate *endDate = [monthBeginFormatter dateFromString:endDateString];
        endDate = [endDate dateByAddingTimeInterval:-1];
        [monthRangeArray addObject:endDate];
        
        [allArray addObject:monthRangeArray];
        DebugNSLog(@"begin %@ end %@",beginDateString, endDateString );
    }
    
    return allArray;
    
}

@end
